package com.innovation.chengzhangriji.ui;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.StateListDrawable;
import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.media.ThumbnailUtils;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v4.view.MotionEventCompat;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.TextureView;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;

import com.innovation.chengzhangriji.Config;
import com.innovation.chengzhangriji.R;
import com.innovation.chengzhangriji.ui.widget.CuteButton;
import com.innovation.chengzhangriji.ui.widget.CuteImageView;
import com.innovation.chengzhangriji.ui.widget.CuteToolbar;
import com.innovation.chengzhangriji.util.FileUtils;
import com.makeramen.roundedimageview.RoundedImageView;
import com.nostra13.universalimageloader.core.ImageLoader;

import java.io.IOException;
import java.util.List;


public class TimelineVideoActivity extends BaseActivity implements View.OnTouchListener, View.OnClickListener, CuteToolbar.OnClickCuteToolbarListener {

    private static final String TAG = "Recorder";

    private FrameLayout mLayoutProgress;

    CuteButton btnRecord;

    private StateListDrawable drawable;

    private boolean record;

    private long firstTime;

    private int length;

    private int width;
    int height;
    private int newWidth;

    private Camera mCamera;
    private TextureView mPreview;
    private MediaRecorder mMediaRecorder;

    /*缩略图*/
    private RoundedImageView mThumbnailView;

    /*删除按钮*/
    private CuteImageView mDeleteButton;

    private String path;

    private String pathS;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setupLayout();
    }

    @Override
    protected void onResume() {
        super.onResume();
        new MediaPrepareTask().execute(null, null, null);
    }

    @Override
    protected void onPause() {
        super.onPause();
        // if we are using MediaRecorder, release it first
        releaseMediaRecorder();
        // release the camera immediately on pause event
        releaseCamera();
    }

    private void setupLayout() {
        setContentView(R.layout.activity_timeline_video);

        CuteToolbar cuteToolbar = (CuteToolbar) findViewById(R.id.toolbar);
        cuteToolbar.setOnClickCuteToolbarListener(this);

        mPreview = (TextureView) findViewById(R.id.texture);
        DisplayMetrics dm = getResources().getDisplayMetrics();
        width = dm.widthPixels;
        height = dm.heightPixels;

        Log.d("width", "" + width);
        Log.d("height", "" + height);

        int h = height - (int) (width * 3 * 1.0f / 4) - (int) (48 * dm.density);
        RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.layout_bottom);
        RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(width, h);
        lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
        relativeLayout.setLayoutParams(lp);

        mLayoutProgress = (FrameLayout) findViewById(R.id.layout_progress);
        btnRecord = (CuteButton) findViewById(R.id.btn_record);
        drawable = new StateListDrawable();
        drawable.addState(new int[]{}, btnRecord.getBackground());
        btnRecord.setBackgroundDrawable(drawable);
        btnRecord.setOnTouchListener(this);

        mThumbnailView = (RoundedImageView) findViewById(R.id.image_thumbnail);
        mThumbnailView.setVisibility(View.INVISIBLE);
        mDeleteButton = (CuteImageView) findViewById(R.id.button_delete);
        mDeleteButton.setVisibility(View.INVISIBLE);
        mThumbnailView.setOnClickListener(this);
        mDeleteButton.setOnClickListener(this);
    }

    @Override
    public void onClickLeft() {
        finish();
    }

    @Override
    public void onClickRight() {
        Intent returnIntent = new Intent();
        Bundle bundle = new Bundle();
        if (TextUtils.isEmpty(path)) {
            finish();
        } else {
            bundle.putString("localUrl", path);
            bundle.putInt("length", length);
            bundle.putString("screenshotUrl", pathS);
            returnIntent.putExtras(bundle);
            setResult(RESULT_OK, returnIntent);
            finish();
        }
    }

    @Override
    public void onClick(View v) {
        if (record || threadRun) {
            return;
        }
        switch (v.getId()) {
            case R.id.image_thumbnail:
                Intent intent = new Intent(this, TimelinePlayActivity.class);
                Bundle bundle = new Bundle();
                bundle.putString("localUrl", path);
                intent.putExtras(bundle);
                startActivity(intent);
                break;
            case R.id.button_delete:
                mThumbnailView.setVisibility(View.INVISIBLE);
                mDeleteButton.setVisibility(View.INVISIBLE);
                FileUtils.deleteFile(path);
                FileUtils.deleteFile(pathS);
                path = null;
                pathS = null;
                break;
        }
    }

    @Override
    public boolean onTouch(View v, MotionEvent ev) {
        if (v.getId() == R.id.btn_record) {
            final int action = MotionEventCompat.getActionMasked(ev);
            switch (action) {
                case MotionEvent.ACTION_DOWN:
                    drawable.setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY);
                    btnRecord.setText("按住拍");
                    if (!threadRun && !record) {
                        if (!TextUtils.isEmpty(path)) {
                            FileUtils.deleteFile(path);
                            FileUtils.deleteFile(pathS);
                        }
                        new Thread(new RecorderRunnable()).start();
                    }
                    break;
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    drawable.clearColorFilter();
                    btnRecord.setText("重新拍");
                    record = false;
                    break;
            }
            return true;
        }
        return false;
    }

    private boolean threadRun = false;

    private class RecorderRunnable implements Runnable {

        private static final int SLEEP = 1000;

        @Override
        public void run() {
            threadRun = true;
            record = true;
            length = 0;
            /*try {
                Thread.sleep(SLEEP);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (!record) {
                Log.d("直接结束不触发", "" + record);
                threadRun = false;
                return;
            }*/

            path = Config.createFile(TimelineVideoActivity.this, Config.VIDEO_DIR).getPath();

            Log.d("path", "" + path);

            mMediaRecorder = new MediaRecorder();
            mCamera.unlock();
            mMediaRecorder.setCamera(mCamera);
            mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
            mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
            mMediaRecorder.setProfile(profile);
            mMediaRecorder.setOutputFile(path);
            mMediaRecorder.setOrientationHint(90);
            try {
                mMediaRecorder.prepare();
            } catch (IllegalStateException e) {
                Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());
                releaseMediaRecorder();
                FileUtils.deleteFile(path);
                threadRun = false;
                return;
            } catch (IOException e) {
                Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
                releaseMediaRecorder();
                FileUtils.deleteFile(path);
                threadRun = false;
                return;
            }
            mMediaRecorder.start();

            while (record && length < Config.VIDEO_MAX_LENGTH) {
                try {
                    int count = 0;
                    while (count < 100) {
                        Thread.sleep(10);
                        newWidth = (int) (width * 1.0f * length / Config.VIDEO_MAX_LENGTH + width * count * 1.0f / 100 / Config.VIDEO_MAX_LENGTH);
                        newWidth = (int) (newWidth * 1.0f / 2);
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) mLayoutProgress.getLayoutParams();
                                lp.setMargins(newWidth, 0, newWidth, 0);
                                mLayoutProgress.setLayoutParams(lp);
                            }
                        });
                        count++;
                    }
                    length++;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            if (length >= 1) {
                releaseMediaRecorder();
                Log.d("length", "录像" + length);

                Bitmap bm = ThumbnailUtils.createVideoThumbnail(path, MediaStore.Video.Thumbnails.MICRO_KIND);
                if (bm == null) {
                    Log.d("bm", "截图失败");
                }
                pathS = FileUtils.saveBitmap(TimelineVideoActivity.this, bm);


                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        ImageLoader.getInstance().displayImage("file://" + pathS, mThumbnailView);
                        mThumbnailView.setVisibility(View.VISIBLE);
                        mDeleteButton.setVisibility(View.VISIBLE);
                        RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) mLayoutProgress.getLayoutParams();
                        lp.setMargins(0, 0, 0, 0);
                        mLayoutProgress.setLayoutParams(lp);
                    }
                });
            } else {
                releaseMediaRecorder();
                FileUtils.deleteFile(path);
                FileUtils.deleteFile(pathS);

                Log.d("length", "录像时间过短");
            }
            threadRun = false;
        }
    }

    private void releaseMediaRecorder() {
        if (mMediaRecorder != null) {
            // clear recorder configuration
            mMediaRecorder.reset();
            // release the recorder object
            mMediaRecorder.release();
            mMediaRecorder = null;
            // Lock camera for later use i.e taking it back from MediaRecorder.
            // MediaRecorder doesn't need it anymore and we will release it if the activity pauses.
            mCamera.lock();
        }
    }

    private void releaseCamera() {
        if (mCamera != null) {
            // release the camera for other applications
            mCamera.release();
            mCamera = null;
        }
    }

    CamcorderProfile profile;

    private boolean prepareVideoRecorder() {

        // BEGIN_INCLUDE (configure_preview)
        mCamera = CameraHelper.getDefaultCameraInstance();
        if(mCamera == null) {
            tipShow("打开相机失败");
            finish();
            return false;
        }
        // We need to make sure that our preview and recording video size are supported by the
        // camera. Query camera to find all the sizes and choose the optimal size given the
        // dimensions of our preview surface.
        Camera.Parameters parameters = mCamera.getParameters();
        List<Camera.Size> mSupportedPreviewSizes = parameters.getSupportedPreviewSizes();
        List<Camera.Size> mSupportedVideoSizes = parameters.getSupportedVideoSizes();
        Camera.Size optimalSizeP = CameraHelper.getOptimalPreviewSize(mSupportedPreviewSizes, width);
        if(mSupportedVideoSizes == null) { // 部分手机这块返回null
            mSupportedVideoSizes = mSupportedPreviewSizes;
        }
        Camera.Size optimalSizeV = CameraHelper.getOptimalPreviewSize(mSupportedVideoSizes, 240);
        // Use the same size for recording profile.

        // QUALITY_QVGA = 7
        if (CamcorderProfile.hasProfile(7)) {
            profile = CamcorderProfile.get(7);
        } else {
            profile = CamcorderProfile.get(CamcorderProfile.QUALITY_LOW);
        }


        profile.videoFrameWidth = optimalSizeV.width;
        profile.videoFrameHeight = optimalSizeV.height;
        profile.audioCodec = MediaRecorder.AudioEncoder.AAC;
        profile.videoCodec = MediaRecorder.VideoEncoder.H264;
        profile.fileFormat = MediaRecorder.OutputFormat.MPEG_4;
        // likewise for the camera object itself.
        // parameters.setPreviewSize(profile.videoFrameWidth, profile.videoFrameHeight);
        parameters.setPreviewSize(optimalSizeP.width, optimalSizeP.height);
        mCamera.setParameters(parameters);
        try {
            // Requires API level 11+, For backward compatibility use {@link setPreviewDisplay}
            // with {@link SurfaceView}
            mCamera.setPreviewTexture(mPreview.getSurfaceTexture());
            mCamera.setDisplayOrientation(90);
            mCamera.startPreview();
        } catch (IOException e) {
            Log.e(TAG, "Surface texture is unavailable or unsuitable" + e.getMessage());
            return false;
        }
        // END_INCLUDE (configure_preview)


        // BEGIN_INCLUDE (configure_media_recorder)
        /*mMediaRecorder = new MediaRecorder();

        // Step 1: Unlock and set camera to MediaRecorder
        mCamera.unlock();
        mMediaRecorder.setCamera(mCamera);

        // Step 2: Set sources
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

        // Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
        mMediaRecorder.setProfile(profile);*/

        return true;

        /*path = Config.createFile(this, Config.VIDEO_DIR).getPath();

        // Step 4: Set output file
        mMediaRecorder.setOutputFile(path);
        // END_INCLUDE (configure_media_recorder)

        // Step 5: Prepare configured MediaRecorder
        try {
            mMediaRecorder.prepare();
        } catch (IllegalStateException e) {
            Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());
            releaseMediaRecorder();
            FileUtils.deleteFile(path);
            return false;
        } catch (IOException e) {
            Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
            releaseMediaRecorder();
            FileUtils.deleteFile(path);
            return false;
        }
        return true;*/
    }

    /**
     * Asynchronous task for preparing the {@link android.media.MediaRecorder} since it's a long blocking
     * operation.
     */
    class MediaPrepareTask extends AsyncTask<Void, Void, Boolean> {

        @Override
        protected Boolean doInBackground(Void... voids) {
            // initialize video camera
            if (prepareVideoRecorder()) {
                // Camera is available and unlocked, MediaRecorder is prepared,
                // now you can start recording
                // mMediaRecorder.start();
            } else {
                // prepare didn't work, release the camera
                releaseMediaRecorder();
                return false;
            }
            return true;
        }

        @Override
        protected void onPostExecute(Boolean result) {

            height = (int) (width * 4 * 1.0f / 3);
            Log.d("最终宽度", "" + width);
            Log.d("最终高度", "" + height);
            RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(width, height);
            lp.addRule(RelativeLayout.BELOW, R.id.toolbar);
            mPreview.setLayoutParams(lp);


            if (!result) {
                finish();
            }
            // inform the user that recording has started
            // setCaptureButtonText("Stop");

        }
    }
}
